#include <iostream>
#include <string>
#include <gmp.h>
#include <gmpxx.h>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <pthread.h>

#define BITS_PER_DIGIT 3.32192809488736234787;

unsigned * numerator;
unsigned iterations;
unsigned points;

void * thread (void * arg) {
	unsigned* mynumerator;
	mynumerator = (unsigned*) arg;

	for (unsigned i = 0; i < iterations; ++i)
	{
		std::cout << "Thread: " << (int)(mynumerator - numerator) << " it: " << i+1 << std::endl;
		for (unsigned j = 0; j < points; ++j)
		{
			double x = rand() / (double)RAND_MAX;
			double y = rand() / (double)RAND_MAX;
			if(x * x + y * y <= 1.) (*mynumerator)++;
		}
	}
	return 0;
}

void monte_carlo(int qtyThreads) {

	for (int i = 0; i < qtyThreads; ++i)
	{
		numerator[i] = 0;
	}
	mpf_class denominator (points);
	denominator *= iterations;
	denominator *= qtyThreads;

	pthread_t * tthreads = new pthread_t[qtyThreads];

	for (int i = 0; i < qtyThreads; ++i)
	{
		pthread_create(tthreads + i, 0, thread, (void *)(numerator + i));
	}
	for (int i = 0; i < qtyThreads; ++i)
	{
		pthread_join(tthreads[i], 0);
	}
	delete tthreads;

	mpf_class tnumerator(0);

	for (int i = 0; i < qtyThreads; ++i)
	{
		tnumerator += numerator[i];
	}
	mpf_class pi(4*tnumerator/denominator);

	
	std::fstream file;
	file.open("MCMT.txt", std::fstream::out);
	file.setf(std::ios::fixed, std::ios::floatfield);
	file.precision(10000000);
	file << pi << std::endl;

}

int main(int argc, char *argv[]) {
	mpf_set_default_prec((long int)(3.32192809488736234787 * 10000100.0));


	std::cout << "Bem vindo ao programa que calcula o PI!\n";
	std::cout << "Esse metodo nao funciona corretamente!\n";
	std::cout << "3-5 casas do pi serao calculadas!\n";
	std::cout << "O arquivo \"MCMT.txt\" sera criado\n";

	int qtyThreads = 10;
	numerator = new unsigned[qtyThreads];

	points = 10000000;
	iterations = 50;

	monte_carlo(qtyThreads);
	delete numerator;
	return 0;
}